/*************************************************************************
    > File Name: face_detect_task.cpp
    > Author: fanzhihui
    > Mail: 953106194@qq.com 
    > Created Time: 2019年06月28日 星期五 11时03分19秒
 ************************************************************************/
#include "face_detect_task.h"
#include "httplib.h"
#include "json/json.h"
#include "config.h"
#include "resposity.h"
#include<iostream>
#include "opencv/cv.h"
#include "image_base64.h"
#include "baidu_face_api.h"
#include "log/logger.h"

using namespace std;
using namespace httplib;
using namespace cv;

void decode(const string& base64,const string& name)
{
	int bin_size = 0;
	string bin = ImageBase64::decode(base64.c_str(),base64.size(),bin_size);

	cv::Mat img_decode;
	vector<uchar> data;
	for (int i = 0; i < bin.size(); ++i){
		data.push_back(bin[i]);
	}
	img_decode = imdecode(data, CV_LOAD_IMAGE_COLOR);

	IplImage dst(img_decode);

	cvSaveImage(name.c_str(), &dst);
}

void FaceDetectTask::Execute(TaskThread* thread_context,void *app_context)
{

	Client client(Config::face_httpd_ip.c_str(), Config::face_httpd_port);
	shared_ptr<Response> res = client.Post("/face/multSearch",packReqBody(),"application/json");

	if( res.get() == NULL) {
		std::cout << "post face/multSearch,but response is null" << std::endl;
		LOG(LOG_ERR,"post face/multSearch,but response is null");
		return;
	}
	if( res->status == 200 ) {
	
		map<string,search_return_t> searched;
		unPackResBody(res->body,searched);

		time_t timestamp = time(NULL);
		Json::Value valueinfo;
		valueinfo["srcImg"] = src_img;
		valueinfo["machineId"] = Config::machine_id;
		valueinfo["timestamp"] = uint32_t(timestamp);

		map<string,search_return_t>::iterator it;
		for( it = searched.begin(); it != searched.end(); ++it ) {

			Json::Value array;	
			uint32_t idx = stoi(it->first.substr(3));
			//array["name"] = tracked_faces[idx].name;
			array["base64"] = tracked_faces[idx].base64;  
			array["faceId"] = it->second.face_id;
			array["score"] = it->second.score;

			array["x"] = tracked_faces[idx].center_x;
			array["y"] = tracked_faces[idx].center_y;
			array["width"] = tracked_faces[idx].width;

			valueinfo["faces"].append(array);
		}
		Json::FastWriter writerinfo;
		string value = writerinfo.write(valueinfo);

		//发布
		string channel = "detects";
		int ret = Resposity::getInstance()->getRedis()->Publish(channel,value);
		std::cout << "channel:" << channel << " ret:" << ret << std::endl;
	
		LOG(LOG_INFO,"publish redis channel:%s,ret:%s",channel.c_str(),ret==0? "success":"failed");
	}
}


string FaceDetectTask::packReqBody()
{
	Json::Value  valueinfo;
	for( uint32_t i = 0; i < tracked_faces.size(); i++) {
		string key = "img" + to_string(i);
		valueinfo[key] = tracked_faces[i].base64;	
	}

	valueinfo["imgNum"] = uint32_t(tracked_faces.size());

	Json::FastWriter writerinfo;
	return writerinfo.write(valueinfo);
	
}


void FaceDetectTask::unPackResBody(const string& body,map<string,search_return_t>& searched)
{
	Json::Reader reader;
	Json::Value json_object;

	if (!reader.parse(body.c_str(), json_object)){

	} else {
		int code = json_object["code"].asInt();
		string message = json_object["message"].asString();
		if( code == 200){
			for( uint32_t i = 0; i < json_object["data"].size(); i++ ) {
				search_return_t ret;
				ret.img_name = json_object["data"][i]["imgName"].asString();
			    ret.face_id = json_object["data"][i]["faceId"].asString();
			    ret.face_key = json_object["data"][i]["faceKey"].asString();
			    ret.score = json_object["data"][i]["score"].asDouble();

				searched[ret.img_name] = ret;
			}
			
		} else {
			LOG(LOG_ERR,"face/multSearch,return code:%d,message:%s",code,message.c_str());
		}
	}
}

